/*****************************************************************************
* Copyright (C) 2013-2020 MulticoreWare, Inc
*
* Authors: Steve Borho <steve@borho.org>
*          Min Chen <chenm003@163.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02111, USA.
*
* This program is also available under a commercial proprietary license.
* For more information, contact us at license @ x265.com.
*****************************************************************************/

#include "common.h"
#include "constants.h"
#include "threading.h"

namespace X265_NS {

#if X265_DEPTH == 12

// lambda = pow(2, (double)q / 6 - 2) * (1 << (12 - 8));
double x265_lambda_tab[QP_MAX_MAX + 1] =
{
    4.0000,    4.4898,    5.0397,    5.6569,     6.3496,
    7.1272,    8.0000,    8.9797,    10.0794,    11.3137,
    12.6992,   14.2544,   16.0000,   17.9594,    20.1587,
    22.6274,   25.3984,   28.5088,   32.0000,    35.9188,
    40.3175,   45.2548,   50.7968,   57.0175,    64.0000,
    71.8376,   80.6349,   90.5097,   101.5937,   114.0350,
    128.0000,  143.6751,  161.2699,  181.0193,   203.1873,
    228.0701,  256.0000,  287.3503,  322.5398,   362.0387,
    406.3747,  456.1401,  512.0000,  574.7006,   645.0796,
    724.0773,  812.7493,  912.2803,  1024.0000,  1149.4011,
    1290.1592, 1448.1547, 1625.4987, 1824.5606,  2048.0000,
    2298.8023, 2580.3183, 2896.3094, 3250.9974,  3649.1211,
    4096.0000, 4597.6045, 5160.6366, 5792.6188,  6501.9947,
    7298.2423, 8192.0000, 9195.2091, 10321.2732, 11585.2375
};

// lambda2 = 0.038 * EXP(0.234 * QP) * 256;
double x265_lambda2_tab[QP_MAX_MAX + 1] =
{
    9.7280,        12.2880,       15.5136,       19.6096,       24.7808, 
    31.3344,       39.6032,       50.0480,       63.2320,       79.8976, 
    100.9664,      127.5904,      161.2544,      203.7504,      257.4848, 
    325.3760,      411.1616,      519.5520,      656.5376,      829.6448, 
    1048.3712,     1324.7744,     1674.0608,     2115.4048,     2673.1264, 
    3377.8944,     4268.4416,     5393.7920,     6815.8464,     8612.8128, 
    10883.5328,    13752.9344,    17378.8160,    21960.6528,    27750.4768, 
    35066.7264,    44311.8848,    55994.4704,    70757.0944,    89411.8144, 
    112984.7552,   142772.5824,   180413.7728,   227978.8800,   288084.2496, 
    364036.0960,   460012.2112,   581291.8784,   734546.3040,   928205.3888, 
    1172921.6256,  1482155.9552,  1872918.2208,  2366702.7968,  2990670.9504, 
    3779144.8832,  4775495.6288,  6034528.7424,  7625499.0080,  9635919.8464, 
    12176377.0368, 15386611.7888, 19443207.2448, 24569301.7344, 31046862.8224, 
    39232197.1968, 49575549.9264, 62645870.6176, 79162109.3632, 100032763.4688
};

#elif X265_DEPTH == 10

// lambda = pow(2, (double)q / 6 - 2) * (1 << (X265_DEPTH - 8));
double x265_lambda_tab[QP_MAX_MAX + 1] =
{
    1.0000, 1.1225, 1.2599, 1.4142, 1.5874, 
    1.7818, 2.0000, 2.2449, 2.5198, 2.8284, 
    3.1748, 3.5636, 4.0000, 4.4898, 5.0397, 
    5.6569, 6.3496, 7.1272, 8.0000, 8.9797, 
    10.0794, 11.3137, 12.6992, 14.2544, 16.0000, 
    17.9594, 20.1587, 22.6274, 25.3984, 28.5088, 
    32.0000, 35.9188, 40.3175, 45.2548, 50.7968, 
    57.0175, 64.0000, 71.8376, 80.6349, 90.5097, 
    101.5937, 114.0350, 128.0000, 143.6751, 161.2699, 
    181.0193, 203.1873, 228.0701, 256.0000, 287.3503, 
    322.5398, 362.0387, 406.3747, 456.1401, 512.0000, 
    574.7006, 645.0796, 724.0773, 812.7493, 912.2803, 
    1024.0000, 1149.4011, 1290.1592, 1448.1547, 1625.4987, 
    1824.5606, 2048.0000, 2298.8023, 2580.3183, 2896.3094,
};

// lambda2 = 0.038 * exp(0.234 * QP) * 16;
double x265_lambda2_tab[QP_MAX_MAX + 1] =
{
    0.6080, 0.7680, 0.9696, 1.2256, 1.5488, 
    1.9584, 2.4752, 3.1280, 3.9520, 4.9936, 
    6.3104, 7.9744, 10.0784, 12.7344, 16.0928, 
    20.3360, 25.6976, 32.4720, 41.0336, 51.8528, 
    65.5232, 82.7984, 104.6288, 132.2128, 167.0704, 
    211.1184, 266.7776, 337.1120, 425.9904, 538.3008, 
    680.2208, 859.5584, 1086.1760, 1372.5408, 1734.4048, 
    2191.6704, 2769.4928, 3499.6544, 4422.3184, 5588.2384, 
    7061.5472, 8923.2864, 11275.8608, 14248.6800, 18005.2656, 
    22752.2560, 28750.7632, 36330.7424, 45909.1440, 58012.8368, 
    73307.6016, 92634.7472, 117057.3888, 147918.9248, 186916.9344, 
    236196.5552, 298468.4768, 377158.0464, 476593.6880, 602244.9904, 
    761023.5648, 961663.2368, 1215200.4528, 1535581.3584, 1940428.9264, 
    2452012.3248, 3098471.8704, 3915366.9136, 4947631.8352, 6252047.7168
};

#else /* !HIGH_BIT_DEPTH */

// lambda = pow(2, (double)q / 6 - 2);
double x265_lambda_tab[QP_MAX_MAX + 1] =
{
    0.2500, 0.2806, 0.3150, 0.3536, 0.3969,
    0.4454, 0.5000, 0.5612, 0.6300, 0.7071,
    0.7937, 0.8909, 1.0000, 1.1225, 1.2599,
    1.4142, 1.5874, 1.7818, 2.0000, 2.2449,
    2.5198, 2.8284, 3.1748, 3.5636, 4.0000,
    4.4898, 5.0397, 5.6569, 6.3496, 7.1272,
    8.0000, 8.9797, 10.0794, 11.3137, 12.6992,
    14.2544, 16.0000, 17.9594, 20.1587, 22.6274,
    25.3984, 28.5088, 32.0000, 35.9188, 40.3175,
    45.2548, 50.7968, 57.0175, 64.0000, 71.8376,
    80.6349, 90.5097, 101.5937, 114.0350, 128.0000,
    143.6751, 161.2699, 181.0193, 203.1873, 228.0701,
    256.0000, 287.3503, 322.5398, 362.0387, 406.3747,
    456.1401, 512.0000, 574.7006, 645.0796, 724.0773
};

// lambda2 = 0.038 * exp(0.234 * QP)
double x265_lambda2_tab[QP_MAX_MAX + 1] =
{
    0.0380, 0.0480, 0.0606, 0.0766, 0.0968,
    0.1224, 0.1547, 0.1955, 0.2470, 0.3121,
    0.3944, 0.4984, 0.6299, 0.7959, 1.0058,
    1.2710, 1.6061, 2.0295, 2.5646, 3.2408,
    4.0952, 5.1749, 6.5393, 8.2633, 10.4419,
    13.1949, 16.6736, 21.0695, 26.6244, 33.6438,
    42.5138, 53.7224, 67.8860, 85.7838, 108.4003,
    136.9794, 173.0933, 218.7284, 276.3949, 349.2649,
    441.3467, 557.7054, 704.7413, 890.5425, 1125.3291,
    1422.0160, 1796.9227, 2270.6714, 2869.3215, 3625.8023,
    4581.7251, 5789.6717, 7316.0868, 9244.9328, 11682.3084,
    14762.2847, 18654.2798, 23572.3779, 29787.1055, 37640.3119,
    47563.9728, 60103.9523, 75950.0283, 95973.8349, 121276.8079,
    153250.7703, 193654.4919, 244710.4321, 309226.9897, 390752.9823
};

#endif

const uint16_t x265_chroma_lambda2_offset_tab[MAX_CHROMA_LAMBDA_OFFSET+1] =
{
       16,    20,    25,    32,    40,    50,
       64,    80,   101,   128,   161,   203,
      256,   322,   406,   512,   645,   812,
     1024,  1290,  1625,  2048,  2580,  3250,
     4096,  5160,  6501,  8192, 10321, 13003,
    16384, 20642, 26007, 32768, 41285, 52015,
    65535
};

uint32_t g_maxLog2CUSize = MAX_LOG2_CU_SIZE;
uint32_t g_maxCUSize     = MAX_CU_SIZE;
uint32_t g_unitSizeDepth = NUM_CU_DEPTH;
uint32_t g_maxCUDepth    = NUM_CU_DEPTH - 1;
uint32_t g_maxSlices     = 1;

const uint32_t g_zscanToRaster[MAX_NUM_PARTITIONS] =
{
    0x00, 0x01, 0x10, 0x11, 0x02, 0x03, 0x12, 0x13, 0x20, 0x21, 0x30, 0x31, 0x22, 0x23, 0x32, 0x33,
    0x04, 0x05, 0x14, 0x15, 0x06, 0x07, 0x16, 0x17, 0x24, 0x25, 0x34, 0x35, 0x26, 0x27, 0x36, 0x37,
    0x40, 0x41, 0x50, 0x51, 0x42, 0x43, 0x52, 0x53, 0x60, 0x61, 0x70, 0x71, 0x62, 0x63, 0x72, 0x73,
    0x44, 0x45, 0x54, 0x55, 0x46, 0x47, 0x56, 0x57, 0x64, 0x65, 0x74, 0x75, 0x66, 0x67, 0x76, 0x77,
    0x08, 0x09, 0x18, 0x19, 0x0A, 0x0B, 0x1A, 0x1B, 0x28, 0x29, 0x38, 0x39, 0x2A, 0x2B, 0x3A, 0x3B,
    0x0C, 0x0D, 0x1C, 0x1D, 0x0E, 0x0F, 0x1E, 0x1F, 0x2C, 0x2D, 0x3C, 0x3D, 0x2E, 0x2F, 0x3E, 0x3F,
    0x48, 0x49, 0x58, 0x59, 0x4A, 0x4B, 0x5A, 0x5B, 0x68, 0x69, 0x78, 0x79, 0x6A, 0x6B, 0x7A, 0x7B,
    0x4C, 0x4D, 0x5C, 0x5D, 0x4E, 0x4F, 0x5E, 0x5F, 0x6C, 0x6D, 0x7C, 0x7D, 0x6E, 0x6F, 0x7E, 0x7F,
    0x80, 0x81, 0x90, 0x91, 0x82, 0x83, 0x92, 0x93, 0xA0, 0xA1, 0xB0, 0xB1, 0xA2, 0xA3, 0xB2, 0xB3,
    0x84, 0x85, 0x94, 0x95, 0x86, 0x87, 0x96, 0x97, 0xA4, 0xA5, 0xB4, 0xB5, 0xA6, 0xA7, 0xB6, 0xB7,
    0xC0, 0xC1, 0xD0, 0xD1, 0xC2, 0xC3, 0xD2, 0xD3, 0xE0, 0xE1, 0xF0, 0xF1, 0xE2, 0xE3, 0xF2, 0xF3,
    0xC4, 0xC5, 0xD4, 0xD5, 0xC6, 0xC7, 0xD6, 0xD7, 0xE4, 0xE5, 0xF4, 0xF5, 0xE6, 0xE7, 0xF6, 0xF7,
    0x88, 0x89, 0x98, 0x99, 0x8A, 0x8B, 0x9A, 0x9B, 0xA8, 0xA9, 0xB8, 0xB9, 0xAA, 0xAB, 0xBA, 0xBB,
    0x8C, 0x8D, 0x9C, 0x9D, 0x8E, 0x8F, 0x9E, 0x9F, 0xAC, 0xAD, 0xBC, 0xBD, 0xAE, 0xAF, 0xBE, 0xBF,
    0xC8, 0xC9, 0xD8, 0xD9, 0xCA, 0xCB, 0xDA, 0xDB, 0xE8, 0xE9, 0xF8, 0xF9, 0xEA, 0xEB, 0xFA, 0xFB,
    0xCC, 0xCD, 0xDC, 0xDD, 0xCE, 0xCF, 0xDE, 0xDF, 0xEC, 0xED, 0xFC, 0xFD, 0xEE, 0xEF, 0xFE, 0xFF
};

const uint32_t g_rasterToZscan[MAX_NUM_PARTITIONS] =
{
    0x00, 0x01, 0x04, 0x05, 0x10, 0x11, 0x14, 0x15, 0x40, 0x41, 0x44, 0x45, 0x50, 0x51, 0x54, 0x55,
    0x02, 0x03, 0x06, 0x07, 0x12, 0x13, 0x16, 0x17, 0x42, 0x43, 0x46, 0x47, 0x52, 0x53, 0x56, 0x57,
    0x08, 0x09, 0x0C, 0x0D, 0x18, 0x19, 0x1C, 0x1D, 0x48, 0x49, 0x4C, 0x4D, 0x58, 0x59, 0x5C, 0x5D,
    0x0A, 0x0B, 0x0E, 0x0F, 0x1A, 0x1B, 0x1E, 0x1F, 0x4A, 0x4B, 0x4E, 0x4F, 0x5A, 0x5B, 0x5E, 0x5F,
    0x20, 0x21, 0x24, 0x25, 0x30, 0x31, 0x34, 0x35, 0x60, 0x61, 0x64, 0x65, 0x70, 0x71, 0x74, 0x75,
    0x22, 0x23, 0x26, 0x27, 0x32, 0x33, 0x36, 0x37, 0x62, 0x63, 0x66, 0x67, 0x72, 0x73, 0x76, 0x77,
    0x28, 0x29, 0x2C, 0x2D, 0x38, 0x39, 0x3C, 0x3D, 0x68, 0x69, 0x6C, 0x6D, 0x78, 0x79, 0x7C, 0x7D,
    0x2A, 0x2B, 0x2E, 0x2F, 0x3A, 0x3B, 0x3E, 0x3F, 0x6A, 0x6B, 0x6E, 0x6F, 0x7A, 0x7B, 0x7E, 0x7F,
    0x80, 0x81, 0x84, 0x85, 0x90, 0x91, 0x94, 0x95, 0xC0, 0xC1, 0xC4, 0xC5, 0xD0, 0xD1, 0xD4, 0xD5,
    0x82, 0x83, 0x86, 0x87, 0x92, 0x93, 0x96, 0x97, 0xC2, 0xC3, 0xC6, 0xC7, 0xD2, 0xD3, 0xD6, 0xD7,
    0x88, 0x89, 0x8C, 0x8D, 0x98, 0x99, 0x9C, 0x9D, 0xC8, 0xC9, 0xCC, 0xCD, 0xD8, 0xD9, 0xDC, 0xDD,
    0x8A, 0x8B, 0x8E, 0x8F, 0x9A, 0x9B, 0x9E, 0x9F, 0xCA, 0xCB, 0xCE, 0xCF, 0xDA, 0xDB, 0xDE, 0xDF,
    0xA0, 0xA1, 0xA4, 0xA5, 0xB0, 0xB1, 0xB4, 0xB5, 0xE0, 0xE1, 0xE4, 0xE5, 0xF0, 0xF1, 0xF4, 0xF5,
    0xA2, 0xA3, 0xA6, 0xA7, 0xB2, 0xB3, 0xB6, 0xB7, 0xE2, 0xE3, 0xE6, 0xE7, 0xF2, 0xF3, 0xF6, 0xF7,
    0xA8, 0xA9, 0xAC, 0xAD, 0xB8, 0xB9, 0xBC, 0xBD, 0xE8, 0xE9, 0xEC, 0xED, 0xF8, 0xF9, 0xFC, 0xFD,
    0xAA, 0xAB, 0xAE, 0xAF, 0xBA, 0xBB, 0xBE, 0xBF, 0xEA, 0xEB, 0xEE, 0xEF, 0xFA, 0xFB, 0xFE, 0xFF
};
    
const uint8_t g_zscanToPelX[MAX_NUM_PARTITIONS] =
{
    0, 4, 0, 4, 8, 12, 8, 12, 0, 4, 0, 4, 8, 12, 8, 12,
    16, 20, 16, 20, 24, 28, 24, 28, 16, 20, 16, 20, 24, 28, 24, 28,
    0, 4, 0, 4, 8, 12, 8, 12, 0, 4, 0, 4, 8, 12, 8, 12,
    16, 20, 16, 20, 24, 28, 24, 28, 16, 20, 16, 20, 24, 28, 24, 28,
    32, 36, 32, 36, 40, 44, 40, 44, 32, 36, 32, 36, 40, 44, 40, 44,
    48, 52, 48, 52, 56, 60, 56, 60, 48, 52, 48, 52, 56, 60, 56, 60,
    32, 36, 32, 36, 40, 44, 40, 44, 32, 36, 32, 36, 40, 44, 40, 44,
    48, 52, 48, 52, 56, 60, 56, 60, 48, 52, 48, 52, 56, 60, 56, 60,
    0, 4, 0, 4, 8, 12, 8, 12, 0, 4, 0, 4, 8, 12, 8, 12,
    16, 20, 16, 20, 24, 28, 24, 28, 16, 20, 16, 20, 24, 28, 24, 28,
    0, 4, 0, 4, 8, 12, 8, 12, 0, 4, 0, 4, 8, 12, 8, 12,
    16, 20, 16, 20, 24, 28, 24, 28, 16, 20, 16, 20, 24, 28, 24, 28,
    32, 36, 32, 36, 40, 44, 40, 44, 32, 36, 32, 36, 40, 44, 40, 44,
    48, 52, 48, 52, 56, 60, 56, 60, 48, 52, 48, 52, 56, 60, 56, 60,
    32, 36, 32, 36, 40, 44, 40, 44, 32, 36, 32, 36, 40, 44, 40, 44,
    48, 52, 48, 52, 56, 60, 56, 60, 48, 52, 48, 52, 56, 60, 56, 60
};

const uint8_t g_zscanToPelY[MAX_NUM_PARTITIONS] =
{
    0, 0, 4, 4, 0, 0, 4, 4, 8, 8, 12, 12, 8, 8, 12, 12,
    0, 0, 4, 4, 0, 0, 4, 4, 8, 8, 12, 12, 8, 8, 12, 12,
    16, 16, 20, 20, 16, 16, 20, 20, 24, 24, 28, 28, 24, 24, 28, 28,
    16, 16, 20, 20, 16, 16, 20, 20, 24, 24, 28, 28, 24, 24, 28, 28,
    0, 0, 4, 4, 0, 0, 4, 4, 8, 8, 12, 12, 8, 8, 12, 12,
    0, 0, 4, 4, 0, 0, 4, 4, 8, 8, 12, 12, 8, 8, 12, 12,
    16, 16, 20, 20, 16, 16, 20, 20, 24, 24, 28, 28, 24, 24, 28, 28,
    16, 16, 20, 20, 16, 16, 20, 20, 24, 24, 28, 28, 24, 24, 28, 28,
    32, 32, 36, 36, 32, 32, 36, 36, 40, 40, 44, 44, 40, 40, 44, 44,
    32, 32, 36, 36, 32, 32, 36, 36, 40, 40, 44, 44, 40, 40, 44, 44,
    48, 48, 52, 52, 48, 48, 52, 52, 56, 56, 60, 60, 56, 56, 60, 60,
    48, 48, 52, 52, 48, 48, 52, 52, 56, 56, 60, 60, 56, 56, 60, 60,
    32, 32, 36, 36, 32, 32, 36, 36, 40, 40, 44, 44, 40, 40, 44, 44,
    32, 32, 36, 36, 32, 32, 36, 36, 40, 40, 44, 44, 40, 40, 44, 44,
    48, 48, 52, 52, 48, 48, 52, 52, 56, 56, 60, 60, 56, 56, 60, 60,
    48, 48, 52, 52, 48, 48, 52, 52, 56, 56, 60, 60, 56, 56, 60, 60
};

const int16_t g_lumaFilter[4][NTAPS_LUMA] =
{
    {  0, 0,   0, 64,  0,   0, 0,  0 },
    { -1, 4, -10, 58, 17,  -5, 1,  0 },
    { -1, 4, -11, 40, 40, -11, 4, -1 },
    {  0, 1,  -5, 17, 58, -10, 4, -1 }
};

const int16_t g_chromaFilter[8][NTAPS_CHROMA] =
{
    {  0, 64,  0,  0 },
    { -2, 58, 10, -2 },
    { -4, 54, 16, -2 },
    { -6, 46, 28, -4 },
    { -4, 36, 36, -4 },
    { -4, 28, 46, -6 },
    { -2, 16, 54, -4 },
    { -2, 10, 58, -2 }
};

const int16_t g_t4[4][4] =
{
    { 64, 64, 64, 64 },
    { 83, 36, -36, -83 },
    { 64, -64, -64, 64 },
    { 36, -83, 83, -36 }
};

const int16_t g_t8[8][8] =
{
    { 64, 64, 64, 64, 64, 64, 64, 64 },
    { 89, 75, 50, 18, -18, -50, -75, -89 },
    { 83, 36, -36, -83, -83, -36, 36, 83 },
    { 75, -18, -89, -50, 50, 89, 18, -75 },
    { 64, -64, -64, 64, 64, -64, -64, 64 },
    { 50, -89, 18, 75, -75, -18, 89, -50 },
    { 36, -83, 83, -36, -36, 83, -83, 36 },
    { 18, -50, 75, -89, 89, -75, 50, -18 }
};

const int16_t g_t16[16][16] =
{
    { 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64 },
    { 90, 87, 80, 70, 57, 43, 25,  9, -9, -25, -43, -57, -70, -80, -87, -90 },
    { 89, 75, 50, 18, -18, -50, -75, -89, -89, -75, -50, -18, 18, 50, 75, 89 },
    { 87, 57,  9, -43, -80, -90, -70, -25, 25, 70, 90, 80, 43, -9, -57, -87 },
    { 83, 36, -36, -83, -83, -36, 36, 83, 83, 36, -36, -83, -83, -36, 36, 83 },
    { 80,  9, -70, -87, -25, 57, 90, 43, -43, -90, -57, 25, 87, 70, -9, -80 },
    { 75, -18, -89, -50, 50, 89, 18, -75, -75, 18, 89, 50, -50, -89, -18, 75 },
    { 70, -43, -87,  9, 90, 25, -80, -57, 57, 80, -25, -90, -9, 87, 43, -70 },
    { 64, -64, -64, 64, 64, -64, -64, 64, 64, -64, -64, 64, 64, -64, -64, 64 },
    { 57, -80, -25, 90, -9, -87, 43, 70, -70, -43, 87,  9, -90, 25, 80, -57 },
    { 50, -89, 18, 75, -75, -18, 89, -50, -50, 89, -18, -75, 75, 18, -89, 50 },
    { 43, -90, 57, 25, -87, 70,  9, -80, 80, -9, -70, 87, -25, -57, 90, -43 },
    { 36, -83, 83, -36, -36, 83, -83, 36, 36, -83, 83, -36, -36, 83, -83, 36 },
    { 25, -70, 90, -80, 43,  9, -57, 87, -87, 57, -9, -43, 80, -90, 70, -25 },
    { 18, -50, 75, -89, 89, -75, 50, -18, -18, 50, -75, 89, -89, 75, -50, 18 },
    {  9, -25, 43, -57, 70, -80, 87, -90, 90, -87, 80, -70, 57, -43, 25, -9 }
};

const int16_t g_t32[32][32] =
{
    { 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64 },
    { 90, 90, 88, 85, 82, 78, 73, 67, 61, 54, 46, 38, 31, 22, 13,  4, -4, -13, -22, -31, -38, -46, -54, -61, -67, -73, -78, -82, -85, -88, -90, -90 },
    { 90, 87, 80, 70, 57, 43, 25,  9, -9, -25, -43, -57, -70, -80, -87, -90, -90, -87, -80, -70, -57, -43, -25, -9,  9, 25, 43, 57, 70, 80, 87, 90 },
    { 90, 82, 67, 46, 22, -4, -31, -54, -73, -85, -90, -88, -78, -61, -38, -13, 13, 38, 61, 78, 88, 90, 85, 73, 54, 31,  4, -22, -46, -67, -82, -90 },
    { 89, 75, 50, 18, -18, -50, -75, -89, -89, -75, -50, -18, 18, 50, 75, 89, 89, 75, 50, 18, -18, -50, -75, -89, -89, -75, -50, -18, 18, 50, 75, 89 },
    { 88, 67, 31, -13, -54, -82, -90, -78, -46, -4, 38, 73, 90, 85, 61, 22, -22, -61, -85, -90, -73, -38,  4, 46, 78, 90, 82, 54, 13, -31, -67, -88 },
    { 87, 57,  9, -43, -80, -90, -70, -25, 25, 70, 90, 80, 43, -9, -57, -87, -87, -57, -9, 43, 80, 90, 70, 25, -25, -70, -90, -80, -43,  9, 57, 87 },
    { 85, 46, -13, -67, -90, -73, -22, 38, 82, 88, 54, -4, -61, -90, -78, -31, 31, 78, 90, 61,  4, -54, -88, -82, -38, 22, 73, 90, 67, 13, -46, -85 },
    { 83, 36, -36, -83, -83, -36, 36, 83, 83, 36, -36, -83, -83, -36, 36, 83, 83, 36, -36, -83, -83, -36, 36, 83, 83, 36, -36, -83, -83, -36, 36, 83 },
    { 82, 22, -54, -90, -61, 13, 78, 85, 31, -46, -90, -67,  4, 73, 88, 38, -38, -88, -73, -4, 67, 90, 46, -31, -85, -78, -13, 61, 90, 54, -22, -82 },
    { 80,  9, -70, -87, -25, 57, 90, 43, -43, -90, -57, 25, 87, 70, -9, -80, -80, -9, 70, 87, 25, -57, -90, -43, 43, 90, 57, -25, -87, -70,  9, 80 },
    { 78, -4, -82, -73, 13, 85, 67, -22, -88, -61, 31, 90, 54, -38, -90, -46, 46, 90, 38, -54, -90, -31, 61, 88, 22, -67, -85, -13, 73, 82,  4, -78 },
    { 75, -18, -89, -50, 50, 89, 18, -75, -75, 18, 89, 50, -50, -89, -18, 75, 75, -18, -89, -50, 50, 89, 18, -75, -75, 18, 89, 50, -50, -89, -18, 75 },
    { 73, -31, -90, -22, 78, 67, -38, -90, -13, 82, 61, -46, -88, -4, 85, 54, -54, -85,  4, 88, 46, -61, -82, 13, 90, 38, -67, -78, 22, 90, 31, -73 },
    { 70, -43, -87,  9, 90, 25, -80, -57, 57, 80, -25, -90, -9, 87, 43, -70, -70, 43, 87, -9, -90, -25, 80, 57, -57, -80, 25, 90,  9, -87, -43, 70 },
    { 67, -54, -78, 38, 85, -22, -90,  4, 90, 13, -88, -31, 82, 46, -73, -61, 61, 73, -46, -82, 31, 88, -13, -90, -4, 90, 22, -85, -38, 78, 54, -67 },
    { 64, -64, -64, 64, 64, -64, -64, 64, 64, -64, -64, 64, 64, -64, -64, 64, 64, -64, -64, 64, 64, -64, -64, 64, 64, -64, -64, 64, 64, -64, -64, 64 },
    { 61, -73, -46, 82, 31, -88, -13, 90, -4, -90, 22, 85, -38, -78, 54, 67, -67, -54, 78, 38, -85, -22, 90,  4, -90, 13, 88, -31, -82, 46, 73, -61 },
    { 57, -80, -25, 90, -9, -87, 43, 70, -70, -43, 87,  9, -90, 25, 80, -57, -57, 80, 25, -90,  9, 87, -43, -70, 70, 43, -87, -9, 90, -25, -80, 57 },
    { 54, -85, -4, 88, -46, -61, 82, 13, -90, 38, 67, -78, -22, 90, -31, -73, 73, 31, -90, 22, 78, -67, -38, 90, -13, -82, 61, 46, -88,  4, 85, -54 },
    { 50, -89, 18, 75, -75, -18, 89, -50, -50, 89, -18, -75, 75, 18, -89, 50, 50, -89, 18, 75, -75, -18, 89, -50, -50, 89, -18, -75, 75, 18, -89, 50 },
    { 46, -90, 38, 54, -90, 31, 61, -88, 22, 67, -85, 13, 73, -82,  4, 78, -78, -4, 82, -73, -13, 85, -67, -22, 88, -61, -31, 90, -54, -38, 90, -46 },
    { 43, -90, 57, 25, -87, 70,  9, -80, 80, -9, -70, 87, -25, -57, 90, -43, -43, 90, -57, -25, 87, -70, -9, 80, -80,  9, 70, -87, 25, 57, -90, 43 },
    { 38, -88, 73, -4, -67, 90, -46, -31, 85, -78, 13, 61, -90, 54, 22, -82, 82, -22, -54, 90, -61, -13, 78, -85, 31, 46, -90, 67,  4, -73, 88, -38 },
    { 36, -83, 83, -36, -36, 83, -83, 36, 36, -83, 83, -36, -36, 83, -83, 36, 36, -83, 83, -36, -36, 83, -83, 36, 36, -83, 83, -36, -36, 83, -83, 36 },
    { 31, -78, 90, -61,  4, 54, -88, 82, -38, -22, 73, -90, 67, -13, -46, 85, -85, 46, 13, -67, 90, -73, 22, 38, -82, 88, -54, -4, 61, -90, 78, -31 },
    { 25, -70, 90, -80, 43,  9, -57, 87, -87, 57, -9, -43, 80, -90, 70, -25, -25, 70, -90, 80, -43, -9, 57, -87, 87, -57,  9, 43, -80, 90, -70, 25 },
    { 22, -61, 85, -90, 73, -38, -4, 46, -78, 90, -82, 54, -13, -31, 67, -88, 88, -67, 31, 13, -54, 82, -90, 78, -46,  4, 38, -73, 90, -85, 61, -22 },
    { 18, -50, 75, -89, 89, -75, 50, -18, -18, 50, -75, 89, -89, 75, -50, 18, 18, -50, 75, -89, 89, -75, 50, -18, -18, 50, -75, 89, -89, 75, -50, 18 },
    { 13, -38, 61, -78, 88, -90, 85, -73, 54, -31,  4, 22, -46, 67, -82, 90, -90, 82, -67, 46, -22, -4, 31, -54, 73, -85, 90, -88, 78, -61, 38, -13 },
    {  9, -25, 43, -57, 70, -80, 87, -90, 90, -87, 80, -70, 57, -43, 25, -9, -9, 25, -43, 57, -70, 80, -87, 90, -90, 87, -80, 70, -57, 43, -25,  9 },
    {  4, -13, 22, -31, 38, -46, 54, -61, 67, -73, 78, -82, 85, -88, 90, -90, 90, -90, 88, -85, 82, -78, 73, -67, 61, -54, 46, -38, 31, -22, 13, -4 }
};

const uint8_t g_chromaScale[ChromaQPMappingTableSize] =
{
    0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 29, 30, 31, 32, 33, 33, 34, 34, 35, 35, 36, 36, 37, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51,
    51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51
};

const uint8_t g_chroma422IntraAngleMappingTable[AngleMapping422TableSize] =
{ 0, 1, 2, 2, 2, 2, 3, 5, 7, 8, 10, 12, 13, 15, 17, 18, 19, 20, 21, 22, 23, 23, 24, 24, 25, 25, 26, 27, 27, 28, 28, 29, 29, 30, 31, DM_CHROMA_IDX };

const uint8_t g_log2Size[MAX_CU_SIZE + 1] =
{
    0, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3,
    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
    6
};

const uint16_t g_scan2x2[][2*2] =
{
    { 0, 2, 1, 3 },
    { 0, 1, 2, 3 },
};

const uint16_t g_scan8x8[NUM_SCAN_TYPE][8 * 8] =
{
    { 0,   8,  1, 16,  9,  2, 24, 17, 10,  3, 25, 18, 11, 26, 19, 27, 32, 40, 33, 48, 41, 34, 56, 49, 42, 35, 57, 50, 43, 58, 51, 59,
      4,  12,  5, 20, 13,  6, 28, 21, 14,  7, 29, 22, 15, 30, 23, 31, 36, 44, 37, 52, 45, 38, 60, 53, 46, 39, 61, 54, 47, 62, 55, 63 },
    { 0,   1,  2,  3,  8,  9, 10, 11, 16, 17, 18, 19, 24, 25, 26, 27,  4,  5,  6,  7, 12, 13, 14, 15, 20, 21, 22, 23, 28, 29, 30, 31,
      32, 33, 34, 35, 40, 41, 42, 43, 48, 49, 50, 51, 56, 57, 58, 59, 36, 37, 38, 39, 44, 45, 46, 47, 52, 53, 54, 55, 60, 61, 62, 63 },
    { 0,   8, 16, 24,  1,  9, 17, 25,  2, 10, 18, 26,  3, 11, 19, 27, 32, 40, 48, 56, 33, 41, 49, 57, 34, 42, 50, 58, 35, 43, 51, 59,
      4,  12, 20, 28,  5, 13, 21, 29,  6, 14, 22, 30,  7, 15, 23, 31, 36, 44, 52, 60, 37, 45, 53, 61, 38, 46, 54, 62, 39, 47, 55, 63 }
};

ALIGN_VAR_16(const uint16_t, g_scan4x4[NUM_SCAN_TYPE + 1][4 * 4]) =
{
    { 0,  4,  1,  8,  5,  2, 12,  9,  6,  3, 13, 10,  7, 14, 11, 15 },
    { 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15 },
    { 0,  4,  8, 12,  1,  5,  9, 13,  2,  6, 10, 14,  3,  7, 11, 15 },
    { 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0 }
};

const uint16_t g_scan16x16[16 * 16] =
{
    0, 16, 1, 32, 17, 2, 48, 33, 18, 3, 49, 34, 19, 50, 35, 51,
    64, 80, 65, 96, 81, 66, 112, 97, 82, 67, 113, 98, 83, 114, 99, 115,
    4, 20, 5, 36, 21, 6, 52, 37, 22, 7, 53, 38, 23, 54, 39, 55,
    128, 144, 129, 160, 145, 130, 176, 161, 146, 131, 177, 162, 147, 178, 163, 179,
    68, 84, 69, 100, 85, 70, 116, 101, 86, 71, 117, 102, 87, 118, 103, 119,
    8, 24, 9, 40, 25, 10, 56, 41, 26, 11, 57, 42, 27, 58, 43, 59,
    192,208, 193,224,209, 194,240,225,210, 195,241,226,211,242,227,243,
    132, 148, 133, 164, 149, 134, 180, 165, 150, 135, 181, 166, 151, 182, 167, 183,
    72, 88, 73, 104, 89, 74, 120, 105, 90, 75, 121, 106, 91, 122, 107, 123,
    12, 28, 13, 44, 29, 14, 60, 45, 30, 15, 61, 46, 31, 62, 47, 63,
    196,212, 197,228,213, 198,244,229,214, 199,245,230,215,246,231,247,
    136, 152, 137, 168, 153, 138, 184, 169, 154, 139, 185, 170, 155, 186, 171, 187,
    76, 92, 77, 108, 93, 78, 124, 109, 94, 79, 125, 110, 95, 126, 111, 127,
    200,216,201,232,217,202,248,233,218,203,249,234,219,250,235,251,
    140, 156, 141, 172, 157, 142, 188, 173, 158, 143, 189, 174, 159, 190, 175, 191,
    204,220,205,236,221,206,252,237,222,207,253,238,223,254,239,255
};

const uint16_t g_scan8x8diag[8 * 8] =
{
    0,   8,  1, 16,  9,  2, 24, 17,
    10,  3, 32, 25, 18, 11,  4, 40,
    33, 26, 19, 12,  5, 48, 41, 34,
    27, 20, 13,  6, 56, 49, 42, 35,
    28, 21, 14,  7, 57, 50, 43, 36,
    29, 22, 15, 58, 51, 44, 37, 30,
    23, 59, 52, 45, 38, 31, 60, 53,
    46, 39, 61, 54, 47, 62, 55, 63
};

const uint16_t g_scan32x32[32 * 32] =
{
    0,32,1,64,33,2,96,65,34,3,97,66,35,98,67,99,128,160,129,192,161,130,224,193,162,131,225,194,163,226,195,227,
    4,36,5,68,37,6,100,69,38,7,101,70,39,102,71,103,256,288,257,320,289,258,352,321,290,259,353,322,291,354,323,355,
    132,164,133,196,165,134,228,197,166,135,229,198,167,230,199,231,8,40,9,72,41,10,104,73,42,11,105,74,43,106,75,107,
    384,416,385,448,417,386,480,449,418,387,481,450,419,482,451,483,260,292,261,324,293,262,356,325,294,263,357,326,295,358,327,359,
    136,168,137,200,169,138,232,201,170,139,233,202,171,234,203,235,12,44,13,76,45,14,108,77,46,15,109,78,47,110,79,111,
    512,544,513,576,545,514,608,577,546,515,609,578,547,610,579,611,388,420,389,452,421,390,484,453,422,391,485,454,423,486,455,487,
    264,296,265,328,297,266,360,329,298,267,361,330,299,362,331,363,140,172,141,204,173,142,236,205,174,143,237,206,175,238,207,239,
    16,48,17,80,49,18,112,81,50,19,113,82,51,114,83,115,640,672,641,704,673,642,736,705,674,643,737,706,675,738,707,739,
    516,548,517,580,549,518,612,581,550,519,613,582,551,614,583,615,392,424,393,456,425,394,488,457,426,395,489,458,427,490,459,491,
    268,300,269,332,301,270,364,333,302,271,365,334,303,366,335,367,144,176,145,208,177,146,240,209,178,147,241,210,179,242,211,243,
    20,52,21,84,53,22,116,85,54,23,117,86,55,118,87,119,768,800,769,832,801,770,864,833,802,771,865,834,803,866,835,867,
    644,676,645,708,677,646,740,709,678,647,741,710,679,742,711,743,520,552,521,584,553,522,616,585,554,523,617,586,555,618,587,619,
    396,428,397,460,429,398,492,461,430,399,493,462,431,494,463,495,272,304,273,336,305,274,368,337,306,275,369,338,307,370,339,371,
    148,180,149,212,181,150,244,213,182,151,245,214,183,246,215,247,24,56,25,88,57,26,120,89,58,27,121,90,59,122,91,123,
    896,928,897,960,929,898,992,961,930,899,993,962,931,994,963,995,772,804,773,836,805,774,868,837,806,775,869,838,807,870,839,871,
    648,680,649,712,681,650,744,713,682,651,745,714,683,746,715,747,524,556,525,588,557,526,620,589,558,527,621,590,559,622,591,623,
    400,432,401,464,433,402,496,465,434,403,497,466,435,498,467,499,276,308,277,340,309,278,372,341,310,279,373,342,311,374,343,375,
    152,184,153,216,185,154,248,217,186,155,249,218,187,250,219,251,28,60,29,92,61,30,124,93,62,31,125,94,63,126,95,127,
    900,932,901,964,933,902,996,965,934,903,997,966,935,998,967,999,776,808,777,840,809,778,872,841,810,779,873,842,811,874,843,875,
    652,684,653,716,685,654,748,717,686,655,749,718,687,750,719,751,528,560,529,592,561,530,624,593,562,531,625,594,563,626,595,627,
    404,436,405,468,437,406,500,469,438,407,501,470,439,502,471,503,280,312,281,344,313,282,376,345,314,283,377,346,315,378,347,379,
    156,188,157,220,189,158,252,221,190,159,253,222,191,254,223,255,904,936,905,968,937,906,1000,969,938,907,1001,970,939,1002,971,1003,
    780,812,781,844,813,782,876,845,814,783,877,846,815,878,847,879,656,688,657,720,689,658,752,721,690,659,753,722,691,754,723,755,
    532,564,533,596,565,534,628,597,566,535,629,598,567,630,599,631,408,440,409,472,441,410,504,473,442,411,505,474,443,506,475,507,
    284,316,285,348,317,286,380,349,318,287,381,350,319,382,351,383,908,940,909,972,941,910,1004,973,942,911,1005,974,943,1006,975,1007,
    784,816,785,848,817,786,880,849,818,787,881,850,819,882,851,883,660,692,661,724,693,662,756,725,694,663,757,726,695,758,727,759,
    536,568,537,600,569,538,632,601,570,539,633,602,571,634,603,635,412,444,413,476,445,414,508,477,446,415,509,478,447,510,479,511,
    912,944,913,976,945,914,1008,977,946,915,1009,978,947,1010,979,1011,788,820,789,852,821,790,884,853,822,791,885,854,823,886,855,887,
    664,696,665,728,697,666,760,729,698,667,761,730,699,762,731,763,540,572,541,604,573,542,636,605,574,543,637,606,575,638,607,639,
    916,948,917,980,949,918,1012,981,950,919,1013,982,951,1014,983,1015,792,824,793,856,825,794,888,857,826,795,889,858,827,890,859,891,
    668,700,669,732,701,670,764,733,702,671,765,734,703,766,735,767,920,952,921,984,953,922,1016,985,954,923,1017,986,955,1018,987,1019,
    796,828,797,860,829,798,892,861,830,799,893,862,831,894,863,895,924,956,925,988,957,926,1020,989,958,927,1021,990,959,1022,991,1023
};

const uint16_t* const g_scanOrder[NUM_SCAN_TYPE][NUM_SCAN_SIZE] =
{
    { g_scan4x4[0], g_scan8x8[0], g_scan16x16, g_scan32x32 },
    { g_scan4x4[1], g_scan8x8[1], g_scan16x16, g_scan32x32 },
    { g_scan4x4[2], g_scan8x8[2], g_scan16x16, g_scan32x32 }
};

const uint16_t* const g_scanOrderCG[NUM_SCAN_TYPE][NUM_SCAN_SIZE] =
{
    { g_scan4x4[0], g_scan2x2[0], g_scan4x4[0], g_scan8x8diag },
    { g_scan4x4[1], g_scan2x2[1], g_scan4x4[0], g_scan8x8diag },
    { g_scan4x4[2], g_scan2x2[0], g_scan4x4[0], g_scan8x8diag }
};

// Table used for encoding the last coefficient position. The index is the position.
// The low 4 bits are the number of "1" in the prefix and the high 4 bits are the number
// of bits in the suffix.
const uint8_t g_lastCoeffTable[32] =
{
    0x00, 0x01, 0x02, 0x03, 0x14, 0x14, 0x15, 0x15,
    0x26, 0x26, 0x26, 0x26, 0x27, 0x27, 0x27, 0x27,
    0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38,
    0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39,
};

// Rice parameters for absolute transform levels
const uint8_t g_goRiceRange[5] = { 7, 14, 26, 46, 78 };

const uint8_t g_lpsTable[64][4] =
{
    { 128, 176, 208, 240 },
    { 128, 167, 197, 227 },
    { 128, 158, 187, 216 },
    { 123, 150, 178, 205 },
    { 116, 142, 169, 195 },
    { 111, 135, 160, 185 },
    { 105, 128, 152, 175 },
    { 100, 122, 144, 166 },
    {  95, 116, 137, 158 },
    {  90, 110, 130, 150 },
    {  85, 104, 123, 142 },
    {  81,  99, 117, 135 },
    {  77,  94, 111, 128 },
    {  73,  89, 105, 122 },
    {  69,  85, 100, 116 },
    {  66,  80,  95, 110 },
    {  62,  76,  90, 104 },
    {  59,  72,  86,  99 },
    {  56,  69,  81,  94 },
    {  53,  65,  77,  89 },
    {  51,  62,  73,  85 },
    {  48,  59,  69,  80 },
    {  46,  56,  66,  76 },
    {  43,  53,  63,  72 },
    {  41,  50,  59,  69 },
    {  39,  48,  56,  65 },
    {  37,  45,  54,  62 },
    {  35,  43,  51,  59 },
    {  33,  41,  48,  56 },
    {  32,  39,  46,  53 },
    {  30,  37,  43,  50 },
    {  29,  35,  41,  48 },
    {  27,  33,  39,  45 },
    {  26,  31,  37,  43 },
    {  24,  30,  35,  41 },
    {  23,  28,  33,  39 },
    {  22,  27,  32,  37 },
    {  21,  26,  30,  35 },
    {  20,  24,  29,  33 },
    {  19,  23,  27,  31 },
    {  18,  22,  26,  30 },
    {  17,  21,  25,  28 },
    {  16,  20,  23,  27 },
    {  15,  19,  22,  25 },
    {  14,  18,  21,  24 },
    {  14,  17,  20,  23 },
    {  13,  16,  19,  22 },
    {  12,  15,  18,  21 },
    {  12,  14,  17,  20 },
    {  11,  14,  16,  19 },
    {  11,  13,  15,  18 },
    {  10,  12,  15,  17 },
    {  10,  12,  14,  16 },
    {   9,  11,  13,  15 },
    {   9,  11,  12,  14 },
    {   8,  10,  12,  14 },
    {   8,   9,  11,  13 },
    {   7,   9,  11,  12 },
    {   7,   9,  10,  12 },
    {   7,   8,  10,  11 },
    {   6,   8,   9,  11 },
    {   6,   7,   9,  10 },
    {   6,   7,   8,   9 },
    {   2,   2,   2,   2 }
};

const uint8_t x265_exp2_lut[64] =
{
    0,  3,  6,  8,  11, 14,  17,  20,  23,  26,  29,  32,  36,  39,  42,  45,
    48,  52,  55,  58,  62,  65,  69,  72,  76,  80,  83,  87,  91,  94,  98,  102,
    106,  110,  114,  118,  122,  126,  130,  135,  139,  143,  147,  152,  156,  161,  165,  170,
    175,  179,  184,  189,  194,  198,  203,  208,  214,  219,  224,  229,  234,  240,  245,  250
};

/* bFilter = g_intraFilterFlags[dir] & trSize */
const uint8_t g_intraFilterFlags[NUM_INTRA_MODE] =
{
    0x38, 0x00,
    0x38, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x20, 0x00, 0x20, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
    0x38, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x20, 0x00, 0x20, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
    0x38, 
};

/* g_depthScanIdx [y][x] */
const uint32_t g_depthScanIdx[8][8] =
{
    {   0,   1,   4,   5,  16,  17,  20,  21,  },
    {   2,   3,   6,   7,  18,  19,  22,  23,  },
    {   8,   9,  12,  13,  24,  25,  28,  29,  },
    {  10,  11,  14,  15,  26,  27,  30,  31,  },
    {  32,  33,  36,  37,  48,  49,  52,  53,  },
    {  34,  35,  38,  39,  50,  51,  54,  55,  },
    {  40,  41,  44,  45,  56,  57,  60,  61,  },
    {  42,  43,  46,  47,  58,  59,  62,  63,  }
};

/* Rec.2020 YUV to RGB Non-constant luminance */
const double g_YUVtoRGB_BT2020[3][3] = 
{
    {   1.00,   0.00,      1.47460,   },
    {   1.00,  -0.16455,  -0.57135,   },
    {   1.00,   1.88140,   0.00,      }
};

const double g_ST2084_PQTable[MAX_HDR_LEGAL_RANGE - MIN_HDR_LEGAL_RANGE + 1] = 
{
    0,
    5.25912035416561E-05, 0.000170826479250824, 0.000342874260206259, 0.000565730978088069,
    0.000838361593599196, 0.0011605708550711, 0.00153261170332205, 0.00195500928122658,
    0.00242846920816411, 0.00295382484798614, 0.00353200479131171, 0.00416401171798929,
    0.00485090808272845, 0.00559380610060962, 0.00639386055422149, 0.00725226351560689,
    0.0081702404049783, 0.00914904700558975, 0.010189967177051, 0.0112943110883226,
    0.0124634138437419, 0.0136986344106386, 0.0150013547814312, 0.0163729793201926,
    0.0178149342559234, 0.0193286672936668, 0.0209156473211494, 0.022577364193536,
    0.0243153285825585, 0.0261310718791221, 0.0280261461406398, 0.0300021240760516,
    0.0320605990628007, 0.0342031851910785, 0.036431517331512, 0.0387472512230819,
    0.0411520635786705, 0.0436476522060052, 0.046235736142162, 0.0489180558000865,
    0.0516963731258075, 0.0545724717652363, 0.0575481572396137, 0.0606252571287911,
    0.0638056212616694, 0.0670911219131892, 0.0704836540073949, 0.0739851353261047,
    0.0775975067228409, 0.0813227323416811, 0.0851627998407477, 0.0891197206201265,
    0.0931955300539647, 0.0973922877266004, 0.101712077672541, 0.106157008620188,
    0.110729214239187, 0.115430853391267, 0.120264110384523, 0.125231195231086,
    0.130334343908053, 0.135575818621706, 0.140957908074883, 0.146482927737596,
    0.152153220120717, 0.157971155052834, 0.163939129960184, 0.170059570149691,
    0.176334929095073, 0.182767688726043, 0.189360359720598, 0.196115481800328,
    0.203035624028883, 0.210123385113499, 0.21738139370961, 0.224812308728624,
    0.232418819648774, 0.240203646829142, 0.248169541826838, 0.256319287717358,
    0.264655699418179, 0.273181624015456, 0.281899941094164, 0.29081356307129,
    0.299925435532481, 0.309238537571936, 0.318755882135647, 0.32848051636804,
    0.338415521962, 0.34856401551231, 0.358929148872555, 0.369514109515577,
    0.380322120897342, 0.391356442824469, 0.402620371825233, 0.414117241524302,
    0.425850423021013, 0.437823325271459, 0.450039395474131, 0.4625021194595,
    0.475215022083238, 0.488181667623337, 0.501405660181076, 0.514890644085913,
    0.528640304304275, 0.542658366852319, 0.556948599212766, 0.571514810755682,
    0.58636085316357, 0.601490620860234, 0.616908051444177, 0.632617126126042,
    0.648621870170268, 0.664926353341107, 0.681534690353104, 0.6984510413256,
    0.715679612242097, 0.733224655413817, 0.751090469947712, 0.769281402219399,
    0.78780184635024, 0.806656244689427, 0.82584908830055, 0.84538491745295,
    0.865268322117971, 0.885503942469945, 0.906096469391926, 0.927050644986733,
    0.948371263092526, 0.970063169803824, 0.99213126399724, 1.01458049786256,
    1.03741587743901, 1.06064246315667, 1.08426537038311, 1.10828976997558,
    1.13272088883845, 1.1575640104859, 1.18282447561067, 1.20850768265765,
    1.23461908840365, 1.26116420854251, 1.28814861827608, 1.31557795291099,
    1.34345790846097, 1.37179424225547, 1.40059277355414, 1.42985938416685,
    1.45960001908056, 1.48982068709166, 1.52052746144494, 1.55172648047831,
    1.58342394827458, 1.61562613531883, 1.6483393791628, 1.68157008509547,
    1.71532472682031, 1.74960984713914, 1.78443205864284, 1.81979804440872,
    1.85571455870433, 1.8921884276992, 1.92922655018235, 1.9668358982877,
    2.0050235182263, 2.04379653102551, 2.0831621332761, 2.12312759788576,
    2.16370027484092, 2.20488759197549, 2.2466970557472, 2.28913625202187,
    2.33221284686502, 2.37593458734142, 2.42030930232274, 2.46534490330251,
    2.51104938521982, 2.55743082729067, 2.60449739384781, 2.65225733518805,
    2.70071898842928, 2.74989077837451, 2.79978121838576, 2.85039891126499,
    2.90175255014517, 2.95385091938954, 3.00670289549934, 3.06031744803115,
    3.11470364052283, 3.16987063142876, 3.22582767506471, 3.2825841225609,
    3.3401494228253, 3.39853312351689, 3.45774487202715, 3.51779441647257,
    3.57869160669604, 3.64044639527875, 3.7030688385618, 3.76656909767725,
    3.83095743959148, 3.89624423815599, 3.96243997517042, 4.02955524145598,
    4.09760073793895, 4.16658727674518, 4.2365257823051, 4.30742729247016,
    4.37930295964014, 4.45216405190141, 4.52602195417663, 4.60088816938553,
    4.67677431961831, 4.75369214731843, 4.83165351647993, 4.91067041385396,
    4.99075495016979, 5.07191936136577, 5.15417600983301, 5.23753738567282,
    5.32201610796449, 5.40762492604782, 5.49437672081637, 5.58228450602463,
    5.67136142960816, 5.76162077501684, 5.85307596256082, 5.94574055077076,
    6.03962823777015, 6.13475286266291, 6.2311284069342, 6.32876899586396,
    6.42768889995753, 6.5279025363866, 6.62942447044656, 6.73226941703026,
    6.83645224211186, 6.94198796425035, 7.04889175610325, 7.15717894596024,
    7.2668650192892, 7.37796562029657, 7.49049655350635, 7.60447378535363,
    7.71991344579293, 7.83683182992318, 7.95524539963073, 8.07517078524564,
    8.19662478721649, 8.31962437780235, 8.44418670277909, 8.57032908316786,
    8.69806901697162, 8.82742418094208, 8.95841243235119, 9.09105181078918,
    9.22536053997842, 9.36135702960081, 9.4990598771529, 9.63848786980913,
    9.77965998631185, 9.92259539887546, 10.0673134751131, 10.2138337799773,
    10.3621760777285, 10.5123603339148, 10.6644067173761, 10.8183356022682,
    10.9741675701064, 11.1319234118292, 11.2916241298841, 11.4532909403319,
    11.6169452749761, 11.782608783511, 11.9503033356888, 12.120051023515,
    12.2918741634627, 12.4657952987048, 12.6418372013776, 12.8200228748588,
    13.0003755560757, 13.1829187178276, 13.367676071144, 13.5546715676512,
    13.7439294019804, 13.9354740141834, 14.1293300921851, 14.3255225742508,
    14.5240766514895, 14.7250177703705, 14.9283716352778, 15.1341642110757,
    15.3424217257167, 15.5531706728631, 15.7664378145379, 15.9822501838117,
    16.2006350874992, 16.4216201089027, 16.6452331105667, 16.8715022370722,
    17.1004559178516, 17.3321228700381, 17.5665321013393, 17.8037129129401,
    18.0436949024415, 18.2865079668192, 18.5321823054235, 18.7807484229967,
    19.0322371327346, 19.2866795593684, 19.5441071422852, 19.8045516386728,
    20.068045126707, 20.3346200087623, 20.6043090146575, 20.8771452049349,
    21.1531619741772, 21.4323930543496, 21.7148725181833, 22.0006347825899,
    22.2897146121093, 22.5821471224015, 22.8779677837589, 23.1772124246723,
    23.4799172354157, 23.7861187716811, 24.0958539582449, 24.4091600926726,
    24.7260748490581, 25.0466362818137, 25.3708828294739, 25.6988533185695,
    26.0305869675189, 26.3661233905639, 26.7055026017538, 27.0487650189598,
    27.3959514679386, 27.7471031864343, 28.1022618283194, 28.4614694677879,
    28.8247686035749, 29.1922021632471, 29.5638135074984, 29.9396464345297,
    30.3197451844465, 30.7041544437129, 31.0929193496474, 31.4860854949729,
    31.8836989324014, 32.2858061792735, 32.6924542222466, 33.1036905220286,
    33.5195630181606, 33.9401201338504, 34.3654107808513, 34.7954843644001,
    35.2303907882032, 35.6701804594619, 36.1149042939698, 36.5646137212482,
    37.0193606897411, 37.4791976720634, 37.944177670299, 38.4143542213633,
    38.8897814024065, 39.3705138362898, 39.8566066971106, 40.3481157157767,
    40.8450971856484, 41.3476079682522, 41.8557054990105, 42.369447793091,
    42.8888934512647, 43.4141016658423, 43.9451322266965, 44.4820455273072,
    45.0249025708978, 45.57376497661, 46.128694985791, 46.6897554682848,
    47.257009928828, 47.8305225135037, 48.4103580162663, 48.9965818855272,
    49.589260230802, 50.1884598294566, 50.794248133489, 51.4066932764077,
    52.0258640801652, 52.6518300621766, 53.2846614424041, 53.9244291505136,
    54.5712048331156, 55.2250608610794, 55.8860703369173, 56.5543071022513,
    57.2298457453516, 57.9127616087739, 58.6031307970611, 59.3010301845114,
    60.0065374230609, 60.7197309502355, 61.4406899971675, 62.1694945967356,
    62.9062255917496, 63.6509646432403, 64.4037942388625, 65.1647977013236,
    65.9340591969731, 66.7116637444152, 67.4976972232724, 68.2922463830112,
    69.0953988518382, 69.9072431457598, 70.7278686776501, 71.5573657664994,
    72.3958256466906, 73.2433404774142, 74.1000033521872, 74.9659083084248,
    75.8411503371909, 76.7258253929696, 77.6200304036002, 78.5238632802992,
    79.4374229277768, 80.3608092544678, 81.2941231828966, 82.2374666600933,
    83.1909426682048, 84.154655235138, 85.1287094453491, 86.1132114507694,
    87.108268481825, 88.1139888585565, 89.1304820019001, 90.1578584450571,
    91.1962298449948, 92.2457089940652, 93.3064098317639, 94.3784474565997,
    95.4619381380949, 96.5569993289116, 97.6637496771184, 98.7823090385655,
    99.9127984894415, 101.055340338899, 102.210058141845, 103.377076711919,
    104.556522134513, 105.748521780005, 106.953204317117, 108.170699726403,
    109.401139313892, 110.644655724874, 111.901382957862, 113.171456378648,
    114.455012734562, 115.752190168864, 117.063128235285, 118.387967912751,
    119.726851620228, 121.079923231788, 122.447328091724, 123.829213029981,
    125.225726377642, 126.637017982633, 128.063239225529, 129.504543035659,
    130.961083907258, 132.43301791588, 133.920502734926, 135.423697652396,
    136.942763587828, 138.477863109372, 140.029160451099, 141.596821530472,
    143.181013966024, 144.781907095212, 146.399671992475, 148.034481487503,
    149.686510183665, 151.355934476676, 153.042932573466, 154.747684511235,
    156.470372176717, 158.211179325695, 159.970291602654, 161.747896560765,
    163.544183681914, 165.359344397174, 167.193572107279, 169.047062203492,
    170.920012088617, 172.812621198221, 174.725091022243, 176.657625126586,
    178.610429175187, 180.583710952171, 182.577680384379, 184.59254956399,
    186.628532771569, 188.685846499193, 190.764709473972, 192.865342681753,
    194.987969391112, 197.13281517763, 199.300107948348, 201.490077966701,
    203.702957877374, 205.938982731875, 208.198390014006, 210.481419665809,
    212.788314113849, 215.119318295558, 217.474679686168, 219.854648325694,
    222.259476846381, 224.689420500319, 227.144737187562, 229.625687484264,
    232.132534671514, 234.665544764103, 237.224986539876, 239.811131569336,
    242.424254245529, 245.064631814346, 247.73254440507, 250.428275061399,
    253.152109772633, 255.904337505438, 258.685250235678, 261.49514298094,
    264.334313833161, 267.203063991664, 270.101697796781, 273.03052276345,
    275.989849615675, 278.979992320954, 282.001268125309, 285.053997588697,
    288.138504620796, 291.255116517118, 294.404163995707, 297.585981234071,
    300.800905906628, 304.049279222569, 307.331445964095, 310.647754525259,
    313.998556950887, 317.384208976364, 320.805070067649, 324.26150346164,
    327.753876207298, 331.28255920701, 334.84792725845, 338.450359096983,
    342.090237438443, 345.767949022632, 349.483884657022, 353.238439261111,
    357.032011911288, 360.865005886229, 364.73782871259, 368.650892211681,
    372.604612546163, 376.59941026756, 380.635710364328, 384.713942310386,
    388.83454011424, 392.997942368521, 397.20459230049, 401.454937822634,
    405.749431584178, 410.088531023082, 414.47269841859, 418.902400944533,
    423.378110722949, 427.900304878816, 432.469465594816, 437.086080167171,
    441.750641062068, 446.463645972511, 451.225597876033, 456.037005092914,
    460.89838134554, 465.81024581748, 470.773123214509, 475.787543825096,
    480.854043582649, 485.973164127686, 491.14545287122, 496.371463058725,
    501.651753834779, 506.986890308486, 512.377443619739, 517.823991006384,
    523.32711587159, 528.887407852831, 534.505462890955, 540.181883300517,
    545.917277840779, 551.712261787277, 557.567457004939, 563.48349202123,
    569.461002100643, 575.500629320033, 581.603022644652, 587.76883800521,
    593.998738375827, 600.29339385279, 606.653481734616, 613.07968660232,
    619.572700401503, 626.133222524762, 632.761959895347, 639.459627051767,
    646.226946233466, 653.064647467273, 659.973468655012, 666.954155662449,
    674.007462408703, 681.134150957274, 688.334991607664, 695.610762988527,
    702.962252151562, 710.390254666907, 717.895574719168, 725.479025205175,
    733.141427832198, 740.883613218127, 748.706420992262, 756.610699897378,
    764.597307893424, 772.667112261926, 780.820989711908, 789.059826487117,
    797.384518474445, 805.79597131351, 814.295100508111, 822.882831538009,
    831.560099973222, 840.327851588798, 849.187042481472, 858.138639187298,
    867.183618801265, 876.322969097945, 885.557688653527, 894.88878696958,
    904.317284598324, 913.844213269149, 923.470616016881, 933.197547311661,
    943.02607318998, 952.957271387842, 962.99223147528, 973.13205499233,
    983.377855587028, 993.730759155025, 1004.19190398011, 1014.7624408779,
    1025.44353334027, 1036.23635768138, 1047.14210318612, 1058.16197226031,
    1069.29718058216, 1080.54895725615, 1091.91854496832, 1103.40720014439,
    1115.01619310819, 1126.74680824381, 1138.60034415848, 1150.57811384819,
    1162.68144486462, 1174.91167948465, 1187.27017488269, 1199.75830330268,
    1212.37745223534, 1225.12902459516, 1238.01443890053, 1251.03512945689,
    1264.19254654015, 1277.48815658428, 1290.92344237023, 1304.49990321753,
    1318.21905517769, 1332.0824312314, 1346.09158148618, 1360.24807337821,
    1374.55349187613, 1389.00943968636, 1403.61753746281, 1418.37942401772,
    1433.29675653564, 1448.37121079053, 1463.60448136459, 1478.99828187054,
    1494.55434517686, 1510.27442363459, 1526.16028930875, 1542.21373421151,
    1558.43657053802, 1574.8306309066, 1591.39776860023, 1608.13985781215,
    1625.05879389502, 1642.15649361107, 1659.43489538767, 1676.89595957601,
    1694.54166871017, 1712.37402777397, 1730.39506446684, 1748.60682947636,
    1767.01139675239, 1785.61086378491, 1804.40735188573, 1823.40300647457,
    1842.59999736598, 1862.00051906422, 1881.60679105712, 1901.42105811765,
    1921.44559060702, 1941.68268478254, 1962.13466310849, 1982.80387457295,
    2003.69269500608, 2024.80352740423, 2046.13880225813, 2067.70097788409,
    2089.4925407609, 2111.51600586931, 2133.77391703832, 2156.2688472933,
    2179.00339921048, 2201.98020527506, 2225.20192824396, 2248.67126151315,
    2272.39092949114, 2296.36368797505, 2320.59232453288, 2345.07965889086,
    2369.82854332463, 2394.84186305701, 2420.1225366596, 2445.67351646045,
    2471.4977889564, 2497.5983752314, 2523.97833137945, 2550.64074893434,
    2577.58875530317, 2604.8255142071, 2632.35422612708, 2660.17812875505,
    2688.30049745283, 2716.72464571406, 2745.45392563483, 2774.49172838938,
    2803.84148471127, 2833.50666538283, 2863.49078172885, 2893.79738611828,
    2924.43007247227, 2955.39247677789, 2986.68827760926, 3018.32119665627,
    3050.29499925996, 3082.61349495315, 3115.28053801072, 3148.30002800544,
    3181.67591037289, 3215.41217698172, 3249.51286671181, 3283.98206604386,
    3318.8239096497, 3354.04258099714, 3389.64231295962, 3425.62738843341,
    3462.00214096588, 3498.770955389, 3535.93826846362, 3573.50856952949,
    3611.48640116911, 3649.87635987397, 3688.68309672536, 3727.91131807909,
    3767.56578626554, 3807.6513202933, 3848.17279656462, 3889.13514960257,
    3930.54337278366, 3972.40251908377, 4014.71770183098, 4057.49409547529,
    4100.73693635754, 4144.45152349895, 4188.64321939905, 4233.31745083673,
    4278.47970969433, 4324.13555378427, 4370.2906076885, 4416.9505636112,
    4464.12118224336, 4511.80829363585, 4560.01779808583, 4608.75566703869,
    4658.02794399743, 4707.84074544526, 4758.20026178446, 4809.11275828399,
    4860.58457604072, 4912.6221329584, 4965.23192473005, 5018.42052584652,
    5072.19459060902, 5126.56085415876, 5181.52613352201, 5237.09732866887,
    5293.28142358609, 5350.08548736398, 5407.51667529896, 5465.58223001341,
    5524.28948258769, 5583.64585370912, 5643.65885483892, 5704.33608939131,
    5765.68525393099, 5827.71413938938, 5890.43063229428, 5953.84271601949,
    6017.95847204743, 6082.78608125617, 6148.33382521752, 6214.610087517,
    6281.62335509419, 6349.38221959681, 6417.89537875378, 6487.17163777577,
    6557.21991076552, 6628.04922215295, 6699.66870814791, 6772.08761821761,
    6845.31531658155, 6919.36128372573, 6994.23511794429, 7069.94653689413,
    7146.5053791833, 7223.92160596987, 7302.20530258909, 7381.36668020537,
    7461.41607748598, 7542.36396229371, 7624.22093341411, 7706.99772229679,
    7790.70519482415, 7875.35435311374, 7960.95633733285, 8047.52242755054,
    8135.06404560776, 8223.5927570193, 8313.12027290238, 8403.65845193137,
    8495.21930231871, 8587.81498382941, 8681.45780982398, 8776.16024932246,
    8871.93492910726, 8968.79463585546, 9066.75231829962, 9165.82108941207,
    9266.0142286397, 9367.34518415456, 9469.8275751412, 9573.47519411942,
    9678.30200930089, 9784.32216698275, 9891.54999396144, 10000
};

}
